/*!
	\file	main.cpp
	 Main file of AEnima application.

	 \author	Paolo Perego E-Mail: thewizard83@hotmail.com\n
				Luca Maggi E-Mail: luca.maggi@polimi.it\n
				Sergio Parini E-Mail: sergio.parini@polimi.it

	\date	2007-09-06 creation \n
		2008-01-24 last modification

	\b COPYRIGHT: 
		This program is property of Sensibilab - Campus Ponit - Lecco
*/

// AEnima - TRAINING SESSION

// SISTEMA
#include <iostream>
#include <stdio.h>

// LOCALI
#include "Constants.h"
#include "SocketComm.h"
#include "GraphicEngine.h"
#include "EventReceiver.h"
#include "SocketThread.h"
#include "EDriverTypes.h"

#include "DealProtocol.h"

#include "myserial.h"

#include <windows.h>

using namespace std;


/*!\fn int main(int argc, char* argv[])
The main.cpp file has been divided into three parts:\n
a first part where the serial and socket communication are initialized using the command line parameters 
and config.txt;\n
a second part where the essential object for the software like protocol, graphics and sound are created;
a third part that is a mega loop in which the graphics and protocols are updated.*/
int main(int argc, char* argv[])
{
	char IPADDRESS[255];
	char PROTOCOL[100];
	char driverSelected[9];
	int hres,vres;
	char mode[10];
	char bitcolor[2],vsinch[5];

	LedDriver	Stimuli;
	if (argc>9)
	{
		// IP ADDRESS (PARAMETER #1)
		sprintf(IPADDRESS,argv[1]);

		// SELECT START PROTOCOL (PARAMETER #2)
		sprintf(PROTOCOL,argv[2]);

		// DRIVER TYPE SELECT (PARAMETER #3)
		sprintf(driverSelected,argv[3]);
	
		// SCREEN RESOLUTION (PARAMETER #4 and #5)
		hres = atoi(argv[4]);
		vres = atoi(argv[5]);

		// VIDEO MODE (PARAMETER #6) WINDOW or FULLSCREEN
		sprintf(mode,argv[6]);
		
		//BITCOLOR
		sprintf (bitcolor,argv[7]);

		//VSINCH
		sprintf (vsinch,argv[8]);

		// SSVEP STIMULATION (PARAMETER #9)
		if (strcmp(argv[9],"NULL")!=0)
		{
			Stimuli.Init(argv[9]);
			Stimuli.Stop();	
		}
		else 
			cout<<"NO SSVEP STIMULATOR"<<endl;
	}
	else 
	{
		char string[255],str_error[255];
		int i=1;
		sprintf(string,"");
		while (i<argc)
		{
			if(i==1)	sprintf(string,argv[i]);
			else sprintf(string,"%s %s",string,argv[i]);
			i++;
		}
		sprintf (str_error,"Ops, the command line parameters are not corrected.\nYou have inserted %s\nthe correct command line is IPADDRESS PROTOCOL_NAME VIDEO_DRIVER VIDEO_HRESOLUTION VIDEO_VRESOLUTION FULLSCREEN COLORBIT VSINCH COM\nPlease correct the command line string and restart AEnima.",string);
		size_t convertedChars=0;
		wchar_t w_str_error[2000];
		mbstowcs_s(&convertedChars,w_str_error,strlen(str_error)+1,str_error,strlen(str_error));
		MessageBox(0,w_str_error,L"ERROR",0);
		exit(-1);
	}	

	// ENGINE
	GraphicEngine	AEngine;
	AEngine.ConfigEngine(driverSelected,hres,vres,mode,bitcolor,vsinch);
	AEngine.InitEngine();
	//AEngine.LoadBuiltInResources();

	// MUSIC
	SoundSystem	MainAudio;
	
	// SOCKET
	SocketComm MainSocket;
	int	isWindowActive = 1;
	
	if(MainSocket.Open(IPADDRESS, SOCK_PORT)< 0) 
	{
		MessageBox(0,L"The IP address that you have inserted is not correct. The program will be closed.",L"ERROR",0);
		return 0;
	}
	MainSocket.Connect();
	CreateRecvThread(&isWindowActive, &MainSocket, &Stimuli, AEngine.device);

	DealProtocol *dealProtocol= new DealProtocol(&AEngine,&MainAudio,&MainSocket,&Stimuli);
	
	// EVENT RECEIVER/MANAGER
	EventReceiver myReceiver(&AEngine,dealProtocol, &Stimuli);
	AEngine.device->setEventReceiver(&myReceiver);
	
	MainAudio.FastPlayFX("..//Media//Music//entry.mp3",1.0f);
	AEngine.SplashScreen();
	if (dealProtocol->runProtocol(PROTOCOL,false)==true)
		exit(-1);
	// GIGALOOP!
	
	while(AEngine.device->run())
	{
		// PROTOCOL EVALUATION
		dealProtocol->EvalProt();
		
		// GRAPHIC ENGINE DRAWINGS
		AEngine.driver->beginScene(true, true, 0);

			AEngine.ExEngine();
			dealProtocol->RunIntoWhile();
		
		AEngine.driver->endScene();

		// SOUND SYSTEM EVENTS
		//...................
		//Sleep(1);
	}
	isWindowActive = 0;
	if (strcmp(argv[4],"NULL")!=0)
			Stimuli.Stop();
	AEngine.device->grab();  //Serve prima di drop altrimenti si impalla
	AEngine.device->drop();
	ReleaseSocketThread();
	close_serial();
	delete dealProtocol;
	return 0;
}
